<?php

namespace app\home\services;

use app\common\loader\ModelMerchant;
use app\common\loader\ModelShop;
use app\common\traits\WechatTrait;
use app\home\loader\Services;
use think\Exception;
use yiqiniu\extend\facade\Db;

/**
 * 积分商城
 */
class PointService extends BaseService
{
    use WechatTrait;

    /**
     * 入口
     * @param string $mkey
     * @return void
     * @throws Exception
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function registerEntry(string $mkey): void
    {
        $merInfo = ModelMerchant::MerchantInfo()->checkMerchantStatus($mkey);
        if (empty($merInfo)) {
            throw  new Exception('经销商不存在或已禁用,请联系经销商.', API_ERROR);
        }
        $result = $this->getOauth(['type' => 4, 'scope' => 0, 'mer_id' => $mkey]);
        header("location:" . $result['url']);

    }

    /**
     * 轮播图列表
     * @param $options
     * @return array
     * @throws Exception
     * @throws \think\db\exception\DbException
     */
    public function bannerList($options)
    {
        return ModelMerchant::MerchantPointMallBanner()->list($options);
    }

    /**
     * 商品列表
     * @param $options
     * @return array
     * @throws Exception
     * @throws \think\db\exception\DbException
     */
    public function productPage($options)
    {
        return ModelMerchant::MerchantProductPoint()->page($options);
    }

    /**
     * 商品详情
     * @param $where
     * @return array
     * @throws Exception
     * @throws \think\db\exception\DbException
     */
    public function productInfo($where, $mer_id)
    {
        $res = ModelMerchant::MerchantProductPoint()->productInfo($where);
        if (empty($res)) {
            throw  new Exception('商品已下架', API_ERROR);
        }
        $res['count'] = ModelMerchant::MerchantOrderPoint()
            ->where('mer_id', $mer_id)
            ->where('status', ORDER_STATUS_SUCCESS)
            ->whereIn('product_code', $res['code'])->count('id');
        ModelMerchant::MerchantProductPoint()->removeOption()->where($where)
            ->update(null, ['show_num' => Db::raw('show_num+1')]);
        return $res;
    }


    /**
     * 分类列表
     * @param array $option
     * @param int $tree
     * @return array|null
     * @throws \think\Exception
     */
    public function classList(array $option): ?array
    {
        return ModelMerchant::MerchantProductPointClass()->classList($option['where'], $option['limit'] ?: 10);
    }


    /**
     * 订单添加
     * @param array $data | product_id , memo , product_num , type , mer_id ,user_id
     * @return int|string
     */
    public function orderAdd(array $data)
    {
        //商品验证
        $product_info = ModelMerchant::MerchantProductPoint()->productInfo(
            ['code' => $data['product_code'], 'mer_id' => $data['mer_id']]);
        if (empty($product_info)) {
            throw  new Exception('商品不存在', API_ERROR);
        }
        if ((int)$product_info['stock_num'] < (int)$data['product_num']) {
            throw  new Exception('商品库存不足', API_ERROR);
        }

        //用户地址信息
        $address = ModelMerchant::MerchantMemberSalesmanAddress()->info([
            'user_id' => $data['user_id'],
            'mer_id' => $data['mer_id'],
            'id' => $data['address_id'],
        ]);
        if (empty($address)) {
            throw  new Exception('请先添加收货地址', API_ERROR_CODE);
        }

        //生成订单
        $order_no = substr(make_unique_no(date('YmdHim')), 0, 16);
        $data = [
            'order_no' => $order_no,
            'mer_id' => $data['mer_id'],
            'product_code' => $data['product_code'],
            'product_title' => $product_info['title'],
            'product_num' => $data['product_num'],
            'sum_point' => $data['product_num'] * $product_info['point'],
            'user_type' => $data['user_type'],
            'user_id' => $data['user_id'],
            'real_name' => $address['real_name'],
            'mobile' => $address['mobile'],
            'address' => $address['province'] . ' ' . $address['city'] . ' ' . $address['county'] . ' ' . $address['address']
        ];

        $res = ModelMerchant::MerchantOrderPoint()->orderSave($data);

        if (empty($res)) {
            throw  new Exception('订单提交失败,请联系供货商', API_ERROR);
        }
        return $order_no;
    }


    /**
     * 订单提交
     * @param $order_no |订单
     * @param $user_id |用户id
     * @param $point |积分
     * @return array
     * @throws Exception
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function orderSubmit($order_no, $user_id)
    {
        $orderModel = ModelMerchant::MerchantOrderPoint();
        $order_info = $orderModel->orderInfo(['order_no' => $order_no, 'user_id' => $user_id]);
        if (empty($order_info)) {
            throw  new Exception('订单不存在', API_ERROR);
        }
        if ((int)$order_info['status'] !== ORDER_STATUS_PENDING) {
            throw  new Exception('订单以支付', API_ERROR);
        }

        $product_info = ModelMerchant::MerchantProductPoint()->productInfo(['code' => $order_info['product_code'], 'mer_id' => $order_info['mer_id']]);
        if (empty($product_info)) {
            throw  new Exception('商品不存在', API_ERROR);
        }
        if ((int)$product_info['stock_num'] < $order_info['product_num']) {
            throw  new Exception('商品库存不足,请联系供货商', API_ERROR);
        }

        try {
            \yiqiniu\extend\facade\Db::startTrans();

            ModelShop::ShopSalesmanPoint()->saveMemberPoint(
                $user_id,
                $order_info['mer_id'],
                $order_info['sum_point'],
                2,
                '积分兑换');
            $orderModel->removeOption()->orderSubmit(
                $user_id,
                $order_no,
                $order_info['product_code'],
                $order_info['product_num'],
                $order_info['mer_id'],
            );

            \yiqiniu\extend\facade\Db::commit();
            return ['order_no' => $order_no, 'sum_point' => $order_info['sum_point']];
        } catch (Exception $e) {
            \yiqiniu\extend\facade\Db::rollback();
            throw  new Exception($e->getMessage(), API_ERROR);
        }

    }


    /**
     * 订单地址修改
     * @param array $data | address_id , order_no , type , mer_id ,user_id
     * @return int|string
     */
    public function orderSaveAddress(array $data)
    {

        $orderModel = ModelMerchant::MerchantOrderPoint();
        $order_info = $orderModel->orderInfo(['order_no' => $data['order_no'], 'user_id' => $data['user_id']]);
        if (empty($order_info)) {
            throw  new Exception('订单不存在', API_ERROR);
        }
        if ((int)$order_info['status'] !== ORDER_STATUS_PENDING) {
            throw  new Exception('订单以支付', API_ERROR);
        }

        //用户地址信息
        $address = ModelMerchant::MerchantMemberSalesmanAddress()->info([
            'user_id' => $data['user_id'],
            'mer_id' => $data['mer_id'],
            'id' => $data['address_id'],
        ]);
        if (empty($address)) {
            throw  new Exception('请先添加收货地址', API_ERROR_CODE);
        }
        //生成订单
        $data = [
            'order_no' => $data['order_no'],
            'mer_id' => $data['mer_id'],
            'real_name' => $address['real_name'],
            'mobile' => $address['mobile'],
            'address' => $address['province'] . ' ' . $address['city'] . ' ' . $address['county'] . ' ' . $address['address']
        ];
        $res = $orderModel->where(['order_no' => $data['order_no'], 'user_id' => $data['user_id']])
            ->update(null, $data);
        if (empty($res)) {
            throw  new Exception('订单修改失败,请联系供货商', API_ERROR);
        }
        return $data['order_no'];
    }


    /**
     * 订单列表
     * @param array $option
     * @param int $tree
     * @return array|null
     * @throws \think\Exception
     */
    public function orderPage(array $option, $mer_id): ?array
    {
        $data = ModelMerchant::MerchantOrderPoint()->page($option);
        if (!empty($data['data'])) {
            $product_img = ModelMerchant::MerchantProductPoint()->where('mer_id', $mer_id)
                ->where('code', 'in', array_column($data['data'], 'product_code'))
                ->column(null, 'pics', 'code');
            foreach ($data['data'] as $key => $v) {
                if (isset($product_img[$v['product_code']])) {
                    $data['data'][$key]['pics'] = $product_img[$v['product_code']];
                } else {
                    $data['data'][$key]['pics'] = '';
                }
            }
        }
        return $data;
    }

    /**
     * 订单详情
     * @param array $where
     * @return array|null
     */
    public function orderInfo(array $where): ?array
    {
        return ModelMerchant::MerchantOrderPoint()->orderInfo($where);
    }

    /**
     * 订单提醒
     * @param  $userid
     * @param  $merid
     * @return array|null
     */
    public function orderRemind($userid, $merid): ?array
    {
        return ModelMerchant::MerchantOrderPoint()->orderRemind($userid, $merid);
    }

    /**
     * 订单取消删除
     * @param  $userid
     * @param  $merid
     * @param  $order_no
     * @return int
     */
    public function orderCancel($userid, $merid, $order_no): int
    {
        return ModelMerchant::MerchantOrderPoint()->orderCancel($userid, $merid, $order_no);
    }

    /**
     * 订单确认收货
     * @param  $userid
     * @param  $merid
     * @param  $order_no
     * @return int
     * @throws \think\db\exception\DbException|Exception
     */
    public function orderFinish($userid, $merid, $order_no): int
    {
        $data = ModelMerchant::MerchantOrderPoint()->orderInfo(['user_id' => $userid, 'mer_id' => $merid, 'order_no' => $order_no]);
        if (empty($data)) {
            throw  new  Exception('订单未找到', API_ERROR);
        }
        if ((int)$data['status'] === ORDER_STATUS_PENDING) {
            throw  new  Exception('订单未未支付请先支付', API_ERROR);
        }
        if ((int)$data['status'] === ORDER_STATUS_SUCCESS) {
            throw  new  Exception('订单已完成', API_ERROR);
        }
        if ((int)$data['status'] === ORDER_STATUS_WAIT_GOODS) {
            throw  new  Exception('订单待发货', API_ERROR);
        }
        if ((int)$data['status'] !== ORDER_STATUS_SEND_GOODS) {
            throw  new  Exception('订单非待完成状态', API_ERROR);
        }
        return ModelMerchant::MerchantOrderPoint()->orderFinish($userid, $merid, $order_no);
    }

    /**
     * 积分列表
     * @param  $option
     */
    public function pointPage($option): array
    {
        return ModelShop::ShopSalesmanPoint()->page($option);
    }


    /**
     * 登录
     * @param string $code
     * @param string $merId
     * @param string $cardVal
     * @param int $app
     * @param string $lng
     * @param string $lat
     * @return mixed
     * @throws Exception
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \yiqiniu\extend\exception\ApiException
     */
    public function wxLogin(string $code, string $merId, int $app)
    {
        $result = [
            'authorization' => '',      //  认证信息
            'openid' => '',             // OPENID
            'user_type' => USER_TYPE_SALESMAN,      // 用户类型
            'userid' => 0,              // 用户编号
            'shop_id' => 0,

        ];
        // 根据code 获取openid
        $wx_info = $this->wxOauth($code);

        $result['openid'] = $wx_info['openid'];
        // 检查商户是否可用
        $mer_info = ModelMerchant::MerchantInfo()->where('mer_id', $merId)->field('mer_id,title,mobile,status,end_time')
            ->find();
        if (empty($mer_info) || $mer_info['status'] !== 1 || $mer_info['end_time'] < date('Y-m-d')) {
            throw new Exception('当前商户不存在', API_ERROR);
        }
        // 导购
        $shoppers = ModelShop::ShopSalesman()->getSalesManForOpenId($merId, $wx_info['openid']);

        if (!$shoppers['sale_man']) {
            throw new Exception('请先注册！', API_ERROR);
        }

        if ($shoppers['sale_man']) {
            $result['userid'] = $shoppers['id'];
            $result['shop_id'] = $shoppers['info']['shop_id'];
        }
        $tokenData = ['userid' => $result['userid'], 'user_type' => $result['user_type'], 'ship_id' => $result['shop_id'], 'mer_id' => $merId, 'open_id' => $wx_info['openid']];

        return [
            'openid' => $wx_info['openid'],
            'userid' => $result['userid'],
            'user_type' => $result['user_type'],
            'authorization' => Services::System()->saveToken($tokenData, $app),
            'mer_info' => [
                'company' => $mer_info['title'] ?? '',
                'mobile' => $mer_info['mobile'] ?? ''
            ]
        ];

    }
}
